#pragma once

#include <iostream>
#include <memory>
#include<sys/wait.h>
#include<functional>
#include "Socket.hpp"

namespace TcpServerModule
{
    using namespace SocketModule;
    using tcphandler_t = std::function<bool(SockPtr,InetAddr)>;
    //TcpServer类只负责流式的IO服务，只负责读写！！
    class TcpServer
    {
    public:
        TcpServer(int port)
        :_listensockp(std::make_unique<TcpSocket>()),
         _isrunning(false),
         _port(port)
        {
        }

        void InitServer(tcphandler_t handler)
        {
            _handler = handler;
            _listensockp->BuildTcpSocketMethod(_port);
        }
        void Loop()
        {
            _isrunning = true;
            printf("TcpServer is running...\n");
            while(_isrunning)
            {
                //1.accept
                InetAddr clientaddr;
                auto sockfd = _listensockp->Accepter(&clientaddr);
                if(nullptr==sockfd)continue;
                //2.IO处理
                std::cout<<"client addr:"<<clientaddr.Addr()<<std::endl;
                // sockfd->Recv();
                // sockfd->Send();
                pid_t id=fork();
                if(id==0)
                {
                    _listensockp->Close();
                    if(fork()>0)exit(0);
                    _handler(sockfd,clientaddr);//多进程执行服务器功能
                    exit(0);
                }
                sockfd->Close();
                waitpid(id,nullptr,0);
            }
            _isrunning=false;
        }

        ~TcpServer()
        {
            _listensockp->Close();
        }

    private:
        // 一定要有一个listensock
        std::unique_ptr<Socket> _listensockp;
        bool _isrunning;
        tcphandler_t _handler;
        int _port;
    };
}